package com.haodf.skeleton

import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.RectF

class ItemRect(var scope: Rect, var skeletonView: SkeletonView) {

    //组成一个 item 的灰条组合
    val rectList: MutableList<RectF> = mutableListOf()

    //一条灰条的高度
    val lineHeight = 60

    //两行之间的间距
    val lineGap = 10
    private val radius = 10f
    private var itemHeight = 0f // 一个 item 的高度
    private val defaultColor = 0xffdcdcdc.toInt()

    //整体区域的参数
    private var x = scope.left.toFloat()//x y点
    private var y = scope.top.toFloat()
    private var scopeRight = scope.right
    private var scopeBottom = scope.bottom

    //移动偏移量
    private var dx = 0f
    private var dy = 0f
    private val scopeF = RectF(scope)


    init {
        createRects()
    }

    private fun createRects() {
        val itemParams = skeletonView.listviewItemType ?: ITEM_TYPE_1

        //根据设置的列数，计算出一个单位的宽度大小
        val lengthUnit = (scope.right - scope.left) / itemParams.columnNum

        var top = Float.MAX_VALUE
        var bottom = Float.MIN_VALUE
        itemParams.params.forEach {
            val line = it.line
            it.graySegments.forEach { segment ->
                val rectF = RectF()
                rectF.top = scope.top + (lineHeight + lineGap) * line + 0f
                rectF.bottom = rectF.top + lineHeight
                if (segment.mergeGap) {
                    rectF.top = rectF.top - lineGap - 2 * radius
                }

                rectF.left = scope.left + lengthUnit * segment.segment.first + 0f

                rectF.right =
                    rectF.left + (segment.segment.second + 1 - segment.segment.first) * lengthUnit

                if (segment.segment.first != 0) {
                    rectF.left = rectF.left + lineGap
                }

                //加入偏移量
                if (segment.horizontalOffset != 0) {
                    rectF.left += segment.horizontalOffset
                    rectF.right += segment.horizontalOffset
                }

                if (segment.verticalOffset != 0) {
                    rectF.top += segment.verticalOffset
                    rectF.bottom += segment.verticalOffset
                }

                //记录item的顶部和底部
                if (rectF.top < top) {
                    top = rectF.top
                }
                if (rectF.bottom > bottom) {
                    bottom = rectF.bottom
                }
                rectList.add(rectF)
            }
        }

        //算出一个 item 的高度，用来重复绘制其余item
        itemHeight = bottom - top + lineHeight + lineGap

        //绘制分割线
        val rectLine = RectF()
        rectLine.left = scope.left + 0f
        rectLine.right = scope.right + 0f

        rectLine.top = bottom + (lineHeight + lineGap) / 2
        rectLine.bottom = rectLine.top + 1

        rectList.add(rectLine)
    }

    private fun nextItem(rect: RectF): RectF {
        val r = RectF(rect)
        //针对每一个灰块，直接纵向位移出一个新灰块
        //是的，不支持横向列表
        r.offset(0f, itemHeight)
        return r
    }

    /**
     * 将一个 item 的样子作为一个整体图，画完就下移一次，继续画第二个 item
     * */
    fun draw(canvas: Canvas) {
        skeletonView.setPaintColor(defaultColor)
        val p = skeletonView.getAPaint()

        rectList.forEach {
            if (scopeF.contains(it)) {
                //绘制一个灰块
                canvas.drawRoundRect(
                    it,
                    radius,
                    radius,
                    p
                )
            }
            //绘制当前灰块在下一个item 中的灰块，直至超出屏幕
            var next = nextItem(it)
            while (itemHeight > lineGap * 2 && scopeF.contains(next)) {
                canvas.drawRoundRect(
                    next,
                    radius,
                    radius,
                    p
                )
                next = nextItem(next)
            }
        }
        // rectList 循环完，即绘制出一个item 的所有灰块，及后面的n 个灰块了。

    }


    companion object {
        val ITEM_TYPE_1 = ItemParams(
            listOf(
                ItemParams.LineSegmentGroup(
                    0,
                    listOf(
                        ItemParams.GraySegment(0 to 1),
                        ItemParams.GraySegment(2 to 6),
                    )
                ),
                ItemParams.LineSegmentGroup(
                    1,
                    listOf(
                        ItemParams.GraySegment(0 to 1, true),
                        ItemParams.GraySegment(2 to 9),
                    )
                ),
                ItemParams.LineSegmentGroup(
                    2,
                    listOf(
                        ItemParams.GraySegment(0 to 1, true),
                        ItemParams.GraySegment(2 to 9),
                    )
                ),
            )
        ).also {
            it.columnNum = 10
        }

        val ITEM_TYPE_2 = ItemParams(
            listOf(
                ItemParams.LineSegmentGroup(
                    0,
                    listOf(
                        ItemParams.GraySegment(0 to 2),
                        ItemParams.GraySegment(4 to 6),
                        ItemParams.GraySegment(9 to 9),
                    )
                ),
                ItemParams.LineSegmentGroup(
                    1,
                    listOf(
                        ItemParams.GraySegment(0 to 6)
                    )
                ),
                ItemParams.LineSegmentGroup(
                    2,
                    listOf(
                        ItemParams.GraySegment(0 to 9)
                    )
                ),
                ItemParams.LineSegmentGroup(
                    3,
                    listOf(
                        ItemParams.GraySegment(0 to 9)
                    )
                )
            )
        ).also {
            it.columnNum = 10
        }
    }
}